package com.youlu.campus.service.course;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.WechatMerchantConfig;
import com.youlu.campus.entity.course.dto.GoodsOrderDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author : [dengbo]
 * @className : WechatPayV3Service
 * @description : [描述说明该类的功能]
 * @createTime : [2022/9/22 13:34]
 */
@Service
@Slf4j
public class WechatPayV3Service {

    public CloseableHttpClient httpClient(WechatMerchantConfig merchantConfig) throws FileNotFoundException {
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create();
        builder.withMerchant(merchantConfig.getMerchantId(), merchantConfig.getSerialNumber(), getMerchantPrivateKey(merchantConfig.getPathPrivateKey()));
        builder.withWechatpay(getCertificate(merchantConfig.getPathPlatformCertificate()));
        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
        CloseableHttpClient httpClient = builder.build();
        return httpClient;
    }

    private List<X509Certificate> getCertificate(String pathPlatformCertificate){
        File file = new File(pathPlatformCertificate);
        FileInputStream  fileInputStream = null;
        try {
            List<X509Certificate> list  = new ArrayList<>(2);
            fileInputStream = new FileInputStream(file);
            list.add(PemUtil.loadCertificate(fileInputStream));
            return  list;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new BusinessException("文件查找不到");
        }finally {
            if(Objects.nonNull(fileInputStream)){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private PrivateKey getMerchantPrivateKey(String pathPrivateKey){
        try {
            File file = new File(pathPrivateKey);
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(file));
            return merchantPrivateKey;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new BusinessException("未找到私钥文件路径");
        }
    }


    public Triple<Boolean, Map, String> profitsharing(GoodsOrderDTO dto, WechatMerchantConfig merchant) throws IOException {
        log.info("WechatMiniService,refund,request param:{}", dto);
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/profitsharing/orders");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("transaction_id", dto.getTransactionId())
                .put("appid", dto.getAppId())
                .put("unfreeze_unsplit",true)
                .put("out_order_no", dto.getOrderNo());
        if (CollectionUtils.isEmpty(dto.getProfitsharingList())) {
            return Triple.of(false, null,"分账账户信息不存在");
        }
        ArrayNode arrayNode = objectMapper.createArrayNode();
        for (GoodsOrderDTO.ProfitsharingDTO item : dto.getProfitsharingList()) {
            String des = StringUtils.isBlank(item.getDescription()) ? "分账" : item.getDescription();
            ObjectNode objectNode = objectMapper.createObjectNode();
            if ("1".equals(item.getType())) {
                objectNode.put("type", "PERSONAL_OPENID");
            } else {
                objectNode.put("type", "MERCHANT_ID");
            }
            objectNode.put("account", item.getAccount())
                    .put("amount", item.getAmount())
                    .put("description", des);
            arrayNode.add(objectNode);
        }
        rootNode.putArray("receivers").addAll(arrayNode);
        objectMapper.writeValue(bos, rootNode);
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient(merchant).execute(httpPost);
        String bodyAsString = EntityUtils.toString(response.getEntity());
        System.out.println(bodyAsString);
        return Triple.of(true, null,bodyAsString);
    }
}
